import { menu } from "../../decorator";
const { ccclass, property } = cc._decorator;

const dirEnum = cc.Enum({
    HORIZONTAL: 1,
    VERTICAL: 2
})

@ccclass
@menu(__filename)
export default class moveAction extends cc.Component {
    @property
    private _target: cc.Node = null;
    @property({ type: cc.Node })
    get target() { return this._target || this.node || null; }
    set target(value) { this._target = value; }

    @property
    private _vector = "x";
    @property
    private _type = dirEnum.HORIZONTAL;
    @property({ type: dirEnum })
    get type() { return this._type; }
    set type(value) { this._type = value; this._vector = this.type === dirEnum.HORIZONTAL ? "x" : "y"; }

    @property({ visible: function () { return this.type === dirEnum.HORIZONTAL } })
    startX = 0;

    @property({ visible: function () { return this.type === dirEnum.HORIZONTAL } })
    endX = 0;

    @property({ visible: function () { return this.type === dirEnum.VERTICAL } })
    startY = 0;

    @property({ visible: function () { return this.type === dirEnum.VERTICAL } })
    endY = 0;

    @property
    speed = 0;

    @property
    private _loop = true;
    @property
    get loop() { return this._loop; }
    set loop(value) {
        this._loop = value;
        if (!value) {
            this.reverse = false;
        }
    }

    @property
    private _reverse = false;
    @property
    get reverse() { return this._reverse; }
    set reverse(value) {
        this._reverse = value;
        if (value) {
            this.loop = true;
        }
    }

    @property
    scaleFollow = false
    @property
    onEnableReset = true

    private _len = 0;
    private _scaleX = 0;
    private _scaleY = 0;
    private _nodeX = 0;
    private _nodeY = 0;
    private _speed = 0;
    private _maxLen = 0;

    onLoad() {
        this._scaleX = this.target.scaleX;
        this._scaleY = this.target.scaleY;
        this._nodeX = this.target.x;
        this._nodeY = this.target.y;
        this._speed = this.speed;

        if (this.type === dirEnum.HORIZONTAL) {
            this._len = (this.target.x - this.startX) / this.speed * Math.abs(this.speed);
            this._maxLen = Math.abs(this.endX - this.startX);
        } else if (this.type === dirEnum.VERTICAL) {
            this._len = (this.target.y - this.startY) / this.speed * Math.abs(this.speed);
            this._maxLen = Math.abs(this.endY - this.startY);
        }
    }

    onEnable() {
        if (this.onEnableReset) {
            this._speed = this.speed;

            if (this.type === dirEnum.HORIZONTAL) {
                this.target.scaleX = this._scaleX;
                this.target.x = this._nodeX;
                this._len = (this.target.x - this.startX) / this.speed * Math.abs(this.speed);
            } else if (this.type === dirEnum.VERTICAL) {
                this.target.scaleY = this._scaleY;
                this.target.y = this._nodeY;
                this._len = (this.target.y - this.startY) / this.speed * Math.abs(this.speed);
            }
        }
    }

    update(dt) {
        if (this._speed) {
            const delta = dt * this._speed;
            // 修改坐标
            this.target[this._vector] += delta;

            // 判断移动距离是否超过限制
            this._len += Math.abs(delta);
            if (this._len > this._maxLen) {
                if (this.loop) {
                    const ratio = this._speed > 0 ? 1 : -1;
                    if (this.reverse) {
                        this._speed *= -1;
                        const out = this._len - this._maxLen;
                        this.target[this._vector] -= out * ratio * 2;
                        if (this.scaleFollow) {
                            this.target["scale" + this._vector.toUpperCase()] *= -1;
                        }
                    } else {
                        this.target[this._vector] -= this._maxLen * ratio;
                    }

                    this._len -= this._maxLen;
                } else {
                    const out = this._len - this._maxLen;
                    const ratio = this._speed > 0 ? 1 : -1;
                    this.target[this._vector] -= out * ratio;
                    this._speed = 0;
                    this._len = this._maxLen;
                }
            }
        }
    }
}